package com.megaspacevr.controller;

import com.megaspacevr.entity.AnonymousUsers;
import com.megaspacevr.entity.Result;
import com.megaspacevr.entity.vo.DeviceInfoVO;
import com.megaspacevr.entity.vo.PageVO;
import com.megaspacevr.entity.vo.UserIdentityVO;
import com.megaspacevr.service.AnonymousUsersService;
import com.megaspacevr.utils.ResultUtil;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.validation.Valid;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.*;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.List;

/**
 * <p>
 * 匿名用户表-用于设备识别 前端控制器
 * </p>
 *
 * @author yezi
 * @since 2025-06-17
 */
@Slf4j
@RestController
@Validated
@RequestMapping("/anonymousUsers")
@Tag(name = "匿名用户管理", description = "匿名用户设备识别相关接口")
@CrossOrigin(origins = "*")
public class AnonymousUsersController {

    @Autowired
    private AnonymousUsersService anonymousUsersService;

    /**
     * 设备识别接口 - 用户访问网站时自动调用
     * @param deviceInfoVO 设备信息
     * @param request HTTP请求
     * @return 用户身份信息
     */
    @PostMapping("/identify")
    @Operation(summary = "设备识别", description = "识别设备并获取或创建匿名用户身份")
    public Result<UserIdentityVO> identifyDevice(@Valid @RequestBody DeviceInfoVO deviceInfoVO, 
                                               HttpServletRequest request) {
        log.info("设备识别请求：{}", deviceInfoVO);
        
        try {
            UserIdentityVO userIdentity = anonymousUsersService.identifyOrCreateUser(deviceInfoVO, request);
            return ResultUtil.success(userIdentity);
        } catch (Exception e) {
            log.error("设备识别失败", e);
            return ResultUtil.fail("设备识别失败，请稍后重试");
        }
    }

    /**
     * 根据用户Token获取用户信息
     * @param userToken 用户唯一标识
     * @return 用户信息
     */
    @GetMapping("/info/{userToken}")
    @Operation(summary = "获取用户信息", description = "根据用户Token获取匿名用户详细信息")
    public Result getUserInfo(@PathVariable String userToken) {
        try {
            var anonymousUser = anonymousUsersService.findByUserToken(userToken);
            if (anonymousUser == null) {
                return ResultUtil.fail("用户不存在");
            }
            
            UserIdentityVO userIdentityVO = new UserIdentityVO();
            userIdentityVO.setUserToken(anonymousUser.getUserToken());
            userIdentityVO.setIsNewUser(false);
            userIdentityVO.setVisitCount(anonymousUser.getVisitCount());
            userIdentityVO.setBookingCount(anonymousUser.getBookingCount());
            
            return ResultUtil.success(userIdentityVO);
        } catch (Exception e) {
            e.printStackTrace();
            return ResultUtil.fail("获取用户信息失败：" + e.getMessage());
        }
    }

    /**
     * 更新用户访问信息（可选接口，主要用于调试）
     * @param userToken 用户唯一标识
     * @return 操作结果
     */
    @PostMapping("/updateVisit/{userToken}")
    @Operation(summary = "更新访问信息", description = "手动更新用户访问信息")
    public Result updateVisitInfo(@PathVariable String userToken) {
        try {
            var anonymousUser = anonymousUsersService.findByUserToken(userToken);
            if (anonymousUser == null) {
                return ResultUtil.fail("用户不存在");
            }
            
            anonymousUsersService.updateVisitInfo(anonymousUser.getId());
            return ResultUtil.success("访问信息更新成功");
        } catch (Exception e) {
            e.printStackTrace();
            return ResultUtil.fail("更新访问信息失败：" + e.getMessage());
        }
    }

    // 管理员接口
    @GetMapping("/admin/getUsers")
    @Operation(summary = "管理员查询匿名用户列表", description = "管理员分页查询匿名用户数据，支持多条件筛选")
    public Result<PageVO<AnonymousUsers>> getAnonymousUsersForAdmin(
            Integer pageNum,
            Integer pageSize,
            @RequestParam(required = false) String searchText,
            @RequestParam(required = false) String startDate,
            @RequestParam(required = false) String endDate,
            @RequestParam(required = false, defaultValue = "desc") String sortType) {
        
        log.info("管理员查询匿名用户列表 - 页码: {}, 页大小: {}, 搜索: {}", pageNum, pageSize, searchText);
        
        PageVO<AnonymousUsers> users = anonymousUsersService.getAnonymousUsersForAdmin(
            pageNum, pageSize, searchText, startDate, endDate, sortType);
        return ResultUtil.success(users);
    }

    @GetMapping("/admin/exportUsers")
    @Operation(summary = "导出匿名用户数据Excel", description = "管理员导出匿名用户数据为Excel文件")
    public ResponseEntity<byte[]> exportAnonymousUsers(
            @RequestParam(required = false) String searchText,
            @RequestParam(required = false) String startDate,
            @RequestParam(required = false) String endDate,
            @RequestParam(required = false, defaultValue = "desc") String sortType) throws IOException {
        
        log.info("开始导出匿名用户列表Excel，参数：searchText={}, startDate={}, endDate={}, sortType={}",
                searchText, startDate, endDate, sortType);

        try {
            // 获取匿名用户列表数据
            List<AnonymousUsers> usersList = anonymousUsersService.getAnonymousUsersListForAdmin(
                searchText, startDate, endDate, sortType);
            log.info("获取到 {} 条数据", usersList.size());

            // 创建工作簿
            try (XSSFWorkbook workbook = new XSSFWorkbook()) {
                Sheet sheet = workbook.createSheet("匿名用户列表");

                // 设置表头样式
                CellStyle headerStyle = workbook.createCellStyle();
                headerStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());
                headerStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
                Font headerFont = workbook.createFont();
                headerFont.setBold(true);
                headerStyle.setFont(headerFont);

                // 创建表头
                Row headerRow = sheet.createRow(0);
                String[] header = {"用户标识", "设备指纹", "IP地址", "浏览器信息", "首次访问时间", 
                                 "最后访问时间", "访问次数", "预约次数", "创建时间"};

                for (int i = 0; i < header.length; i++) {
                    Cell cell = headerRow.createCell(i);
                    cell.setCellValue(header[i]);
                    cell.setCellStyle(headerStyle);
                    sheet.autoSizeColumn(i);
                }

                // 填充数据
                int rowNum = 1;
                for (AnonymousUsers user : usersList) {
                    Row row = sheet.createRow(rowNum++);
                    row.createCell(0).setCellValue(user.getUserToken());
                    row.createCell(1).setCellValue(user.getDeviceFingerprint());
                    row.createCell(2).setCellValue(user.getIpAddress());
                    row.createCell(3).setCellValue(user.getUserAgent());
                    
                    // 设置首次访问时间
                    Cell firstVisitTimeCell = row.createCell(4);
                    firstVisitTimeCell.setCellValue(user.getFirstVisitTime());
                    CellStyle dateStyle = workbook.createCellStyle();
                    dateStyle.setDataFormat(workbook.createDataFormat().getFormat("yyyy-mm-dd hh:mm"));
                    firstVisitTimeCell.setCellStyle(dateStyle);
                    
                    // 设置最后访问时间
                    Cell lastVisitTimeCell = row.createCell(5);
                    lastVisitTimeCell.setCellValue(user.getLastVisitTime());
                    lastVisitTimeCell.setCellStyle(dateStyle);
                    
                    row.createCell(6).setCellValue(user.getVisitCount() != null ? user.getVisitCount() : 0);
                    row.createCell(7).setCellValue(user.getBookingCount() != null ? user.getBookingCount() : 0);
                    
                    // 设置创建时间
                    Cell createTimeCell = row.createCell(8);
                    createTimeCell.setCellValue(user.getCreatedAt());
                    createTimeCell.setCellStyle(dateStyle);
                }

                // 写入字节数组
                ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
                workbook.write(outputStream);
                byte[] content = outputStream.toByteArray();

                // 设置响应头
                HttpHeaders headers = new HttpHeaders();
                headers.setContentType(MediaType.parseMediaType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"));
                String filename = URLEncoder.encode("匿名用户列表.xlsx", StandardCharsets.UTF_8).replaceAll("\\+", "%20");
                headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename*=UTF-8''" + filename);

                log.info("Excel文件生成成功，大小: {} bytes", content.length);
                return new ResponseEntity<>(content, headers, HttpStatus.OK);
            }
        } catch (Exception e) {
            log.error("导出Excel失败", e);
            throw new RuntimeException("导出Excel失败: " + e.getMessage());
        }
    }

    @GetMapping("/admin/statistics")
    @Operation(summary = "匿名用户统计", description = "获取匿名用户访问统计数据")
    public Result<Object> getUserStatistics() {
        log.info("获取匿名用户统计数据");
        
        try {
            // 可以添加更多统计逻辑
            long userCount = anonymousUsersService.count();
            
            // 构建统计数据
            return ResultUtil.success(new Object() {
                public final long totalUsers = userCount;
                public final String message = "用户统计数据获取成功";
            });
        } catch (Exception e) {
            log.error("获取用户统计数据失败", e);
            return ResultUtil.fail("获取统计数据失败");
        }
    }
}
